问题描述
在开发一个项目中,本地用 TableView 进行服务器的数据展示.但是最后发现,数据每隔几条就重复.通过
charles 抓取服务器端返回的数据.没有任何问题.也就是说是本地的处理方式出了问题.
问题定位
本地的 UI 逻辑比较简单.所以可以很轻松的断定是 UITableView 的重用机制导致了这个问题.以下是核心代码:
1 | -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath |
问题解决
废掉重用机制的尝试
一开始,也是最容易想到的办法,就是直接不用重用机制了.也就是将下面的代码:
1 | GQContentListCell * contentCell = [tableView dequeueReusableCellWithIdentifier:reuseid]; |
改成:
1 | GQContentListCell * contentCell = nil; |
好了,问题解决了.
但是用脚趾头想想也知道,这样是不行的.因为一旦数据多起来,不卡才怪!
最终方案
静下来想,苹果做一件事情,一定不会这么弱智.所以问题肯定还是出在自己身上.
最终将 if 里面的代码拿出来,问题解决:
最终代码
1 | -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath |
方案说明
假设一屏幕能显示 n 个 cell ,那么可以认为能被实例化的 cell 个数是 n+1 (或者其他,但是不会偏差太多).
那么从 n+2 个开始,就会复用前面的的 cell ,也就是说 cell==nil 这个条件就不成立了,所以 if 里面的代码就不会执行. 所以,在里面的给模型赋值的代码也就失效了. tableView 显示的数据永远就是那 n+1 个.
结论
重用 cell 的时候, 所有给数据重新赋值的操作都应该拿到 if 外面执行